/*
 * Copyright 2008-2009 ArtisanLogic.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.artisanlogic.io;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

// =====================================================================================================================
// Utils.java                                                                                    Created on Feb 18, 2009
// ---------------------------------------------------------------------------------------------------------------------
/**
 * This class is a collection of static utility functions for I/O operations.
 * 
 * @author sean@artisanlogic.com
 * @author john@artisanlogic.com
 * @since 0.9-Beta
 */
// =====================================================================================================================
public class Utils {
  
  // -------------------------------------------------------------------------------------------------------------------
  // constructors
  // -------------------------------------------------------------------------------------------------------------------

  /*
   * Private constructor to restrict usage to static methods only
   */
  private Utils() {}
  
  // -------------------------------------------------------------------------------------------------------------------
  // public static methods
  // -------------------------------------------------------------------------------------------------------------------
  
  /**
   * This method reads character data from the resource identified by the specified URL and provides access to a String 
   * representation of the data.
   * 
   * @param url This parameter holds the URL identifying the resource that the character data should be read from.
   * @return This method returns a String representation of the data read from the resource identified by the specified 
   *  URL.
   * @throws RuntimeException This method throws an instance of RuntimeException if an unrecoverable error condition is
   *  encountered while reading content from the resource identified by the provided URL.
   */
  public static String readContent(final URL url) throws RuntimeException {
    ByteArrayOutputStream to = new ByteArrayOutputStream();
    copyContent(url, to);
    return new String(to.toByteArray());
  }

  /**
   * This method copies data from the resource identified by the specified URL into the provided OutputStream.
   * 
   * @param url This parameter holds the URL identifying the resource that data should be read from.
   * @param to This parameter holds the OutputStream destination of the data read from the resource identified by the 
   *  specified URL.
   * @throws RuntimeException This method throws an instance of RuntimeException if an unrecoverable error condition is
   *  encountered while copying content from the resource identified by the provided URL into the specified 
   *  OutputStream.
   */
  public static void copyContent(final URL url, final OutputStream to) throws RuntimeException {
    new ClosingStreamTemplate<InputStream>().withStream(new StreamTask<InputStream>() {
      public InputStream getStream() throws Exception {
        return url.openConnection().getInputStream();
      }
      public void execute(InputStream from) throws Exception {
        copyData(from, to);
      }
    });
  }

  /**
   * This method copies data from the provided InputStream to the provided OutputStream.
   * 
   * @param from This parameter holds the InputStream source of the data to be copied to the specified OutputStream.
   * @param to This parameter holds the OutputStream destination of the data to be copied from the specified 
   *  InputStream.
   * @throws Exception This method throws an instance of IOException if an unrecoverable error condition is encountered
   *  while delegating to the provided streams to perform the copy. 
   */
  public static void copyData(final InputStream from, final OutputStream to) throws IOException {
    byte[] buffer = new byte[8192];
    for(int length = 0; (length = from.read(buffer)) > 0;) {
      to.write(buffer, 0, length);
    }
  }

}
